home *** CD-ROM | disk | FTP | other *** search
- /*
- These are some IFF file handler routines...
- */
-
- #define IFF_STUFF_C 1
-
- #ifndef IFF_H
- #include "iff.h"
- #endif
-
- UBYTE iff_disk_buffer[4096]; /* a 4K disk buffer to speed I/O to file */
- SHORT iff_buffer_size; /* these are not used at the moment */
- SHORT iff_buffer_position; /* but I figure they may come in handy */
- ULONG iff_file_position; /* sometime. Only 8 bytes, no biggie */
-
-
-
-
- /*
- $doc PullID
- Function: PullID(buffer)
-
- Inputs: char *buffer;
-
- Synopsis: PullID() is done here as an actual subroutine, although
- it could just as easily be set up as a macro with a
- #define. All it does is takes a pointer to a text buffer
- and yanks out the first four bytes and shifts them into a
- ULONG, then returns it.
-
- Returns: returns a ULONG number.
-
- Bugs: None
- $end
- */
-
- ULONG PullID(what)
- UBYTE *what;
- {
- return (ULONG)((ULONG)what[0]<<24 | (ULONG)what[1]<<16 | (ULONG)what[2]<<8 | (ULONG)what[3]);
- }
-
-
- /*
- $doc GetBMHD
- Function: GetBMHD(iff_file,header)
-
- Inputs: FILE *iff_file;
- BitMapHeader *header;
-
- Synopsis: GetBMHD() searches the IFF file for a bitmap header and
- reads the information into the BitMapHeader, one field at
- a time. This coud be made considerably faster and simpler
- by doing a memcpy() from the disk buffer instead, but this
- way makes it more clear what is in the BitMapHeader and
- the relative positions within the file, so I'll leave it
- like it is.
-
- Returns: TRUE on error, FALSE on success.
-
- Bugs: None known.
-
- See Also: iff.h (contains the BitMapHeader structure).
- $end
- */
-
- BOOL GetBMHD(ifffile,header)
- FILE *ifffile;
- BitMapHeader *header;
- {
- Chunk bmhdchunk;
- BOOL error;
- /* first find the chunk */
- error=FindChunk(ifffile,MakeID('B','M','H','D'),&bmhdchunk);
- if(error)
- return TRUE; /* read the data into header */
- header->w = ((UWORD)(bmhdchunk.ckdata[0]) << 8) | (bmhdchunk.ckdata[1]);
- header->h = ((UWORD)(bmhdchunk.ckdata[2]) << 8) | (bmhdchunk.ckdata[3]);
- header->x = ((WORD)(bmhdchunk.ckdata[4]) << 8) | (bmhdchunk.ckdata[5]);
- header->y = ((WORD)(bmhdchunk.ckdata[6]) << 8) | (bmhdchunk.ckdata[7]);
- header->nplanes = bmhdchunk.ckdata[8];
- header->masking = bmhdchunk.ckdata[9];
- header->compression = bmhdchunk.ckdata[10];
- header->pad1 = 0; /* set to 0 and skip over a byte */
- header->TransparentColor = (UWORD)(bmhdchunk.ckdata[12] << 8) | (bmhdchunk.ckdata[13]);
- header->xAspect = bmhdchunk.ckdata[14];
- header->yAspect = bmhdchunk.ckdata[15];
- header->pageWidth = ((WORD)(bmhdchunk.ckdata[16]) << 8) | (bmhdchunk.ckdata[17]);
- header->pageHeight = ((WORD)(bmhdchunk.ckdata[18]) << 8) | (bmhdchunk.ckdata[19]);
- FreeMem(bmhdchunk.ckdata,bmhdchunk.cksize); /* free memory */
- return FALSE;
- }
-
- /*
- $doc GetViewModes
- Function: GetViewModes(newscreen, iff_file)
-
- Inputs: struct NewScreen *newscreen;
- FILE *iff_file;
-
- Synopsis: GetViewModes() looks for a CAMG chunk in the IFF file.
- If it finds one, it stores the ViewModes word into the
- NewScreen structure. If there isn't, it sets up the
- minimal assumptions necessary to open the screen properly
- (i.e. lace or not and hires or not).
-
- Returns: TRUE on error, FALSE on success.
-
- Bugs: Makes no assumptions about the extended screen modes found
- under WorkBench 2.0, so that this will work on 1.3 machines.
- Most fancy-screen-mode pictures should probably have a CAMG
- chunk in them anyway.
- $end
- */
-
- BOOL GetViewModes(newscreen,ifffile)
- struct NewScreen *newscreen;
- FILE *ifffile;
- {
- BOOL error = FALSE;
- Chunk camgchunk;
-
- error = FindChunk(ifffile,MakeID('C','A','M','G'),&camgchunk);
- if(!error)
- {
- newscreen->ViewModes = PullID(camgchunk.ckdata) & CAMGMASK;
- FreeMem(camgchunk.ckdata,camgchunk.cksize);
- }
- if(newscreen->Width > 384) /* if no CAMG chunk, make it up */
- newscreen->ViewModes |= HIRES; /* if there was one, this won't */
- if(newscreen->Height > 200) /* hurt anything to double-check */
- newscreen->ViewModes |= LACE;
- return FALSE;
- }
-
- /*
- $doc FindChunk
- Function: FindChunk(iff_file,chunktype,chunk)
-
- Inputs: FILE *iff_file;
- ULONG chunktype;
- Chunk chunk;
-
- Synopsis: FindChunk searches an IFF file for a chunk of type
- chunktype. It makes use of the iff_disk_buffer for
- speedier I/O. The buffer could be diddled with a little
- to improve speed, but you might wind up with overkill on
- the reads (probably already a lot of that at 4K). If it
- finds the chunk, it allocates memory for the chunk body
- UNLESS it is a BODY type chunk. It then reads the data
- into the chunkdata section and returns. It is up to the
- caller to free the allocated memory. If it is looking for
- a BODY type chunk, rather than allocate memory for the
- body, it leaves this part up to the caller (useful for
- on-the-fly decompression), and instead positions the IFF
- file pointer so that it points to the start of the BODY
- chunk data.
-
- Returns: TRUE on error, FALSE on success.
-
- Bugs: None known.
- $end
- */
-
- BOOL FindChunk(ifffile,chunktype,chunk)
- FILE *ifffile;
- ULONG chunktype;
- Chunk *chunk;
- {
- SHORT temppos;
- BOOL foundchunk= FALSE;
- ULONG bytes_read=0,seek_spot=0;
- SHORT buffer_size=0;
-
- rewind(ifffile); /* start at top of file */
- buffer_size = fread(iff_disk_buffer,1,4096,ifffile); /* fill buffer */
- while(TRUE) /* search whole file for chunk */
- {
- for(temppos=0;temppos<buffer_size;temppos++) /* scan buffer */
- if(PullID(&iff_disk_buffer[temppos]) == chunktype)
- {
- foundchunk = TRUE; /* found chunk type ? */
- break;
- }
- if((foundchunk) || feof(ifffile)) /* done ? */
- break;
- buffer_size = fread(iff_disk_buffer,1,4096,ifffile);
- bytes_read += buffer_size; /* how far are we into file? */
- };
- seek_spot = bytes_read + temppos + 8; /* for a BODY chunk */
- if(foundchunk)
- {
- chunk->ckID = PullID(&iff_disk_buffer[temppos]);
- chunk->cksize = PullID(&iff_disk_buffer[temppos+4]);
- if(chunk->ckID == MakeID('B','O','D','Y'))
- {
- chunk->ckdata = NULL; /* fix file pointer */
- fseek(ifffile,seek_spot,SEEK_SET);
- return FALSE; /* I'm outta here... */
- }
- chunk->ckdata = (UBYTE *)AllocMem(chunk->cksize,MEMF_CLEAR);
- if(chunk->ckdata == NULL) /* not a BODY chunk at this point */
- {
- printf("\nNo memory for chunk!!\n");
- return TRUE;
- }
- temppos += 8; /* read the data into the chunkdata section */
- for(bytes_read=0;bytes_read<chunk->cksize;bytes_read++)
- chunk->ckdata[bytes_read] = iff_disk_buffer[temppos++];
- }
- else
- return TRUE; /* hey, somethin' ain't right */
- return FALSE; /* everything's fine */
- }
-
- /*
- $doc GetColorMap
- Function: GetColorMap(iff_file,colortable)
-
- Inputs: FILE *iff_file;
- UWORD *colortable;
-
- Synopsis: GetColorMap scans an IFF file for a colormap, loading it
- into the colortable array given.
-
- Returns: A SHORT describing the number of colors in the table.
-
- Bugs: The caller should be sure that the color table is large
- enough to hold the colormap. This routine will be perfectly
- happy to cram a 32-color colormap into an array that only
- holds 16, which would lead to highly unpredictable
- behavior and undesired results.
- $end
- */
-
- SHORT GetColorMap(ifffile,colortable)
- FILE *ifffile;
- UWORD *colortable;
- {
- Chunk cmapchunk;
- SHORT count=0;
- BOOL error = FALSE;
- UWORD red,green,blue;
-
- error = FindChunk(ifffile,MakeID('C','M','A','P'),&cmapchunk);
- if(!error) /* found colormap? */
- { /* make RGB4's out of it */
- for(;count<cmapchunk.cksize/3;count++)
- {
- red = cmapchunk.ckdata[(count*3)] >> 4; /* use high order 4 bits */
- green = cmapchunk.ckdata[(count*3)+1] >> 4;
- blue = cmapchunk.ckdata[(count*3)+2] >> 4;
- colortable[count] = blue;
- colortable[count] |= green << 4;
- colortable[count] |= red << 8;
- }
- FreeMem(cmapchunk.ckdata,cmapchunk.cksize);
- }
- return (count);
- }
-
-
- /*
- $doc ReadPic
- Function: ReadPic(bitmap,iff_file,header)
-
- Inputs: struct BitMap *bitmap;
- FILE *iff_file;
- BitMapHeader *header;
-
- Synopsis: ReadPic() is the picture reader. It takes a pointer to
- a bitmap, a pointer to a file which need not be at any
- particular position, (it will find the data with
- FindChunk()), and a pointer to a BitMapHeader describing
- the picture being read. It doesn't matter whether the
- picture is on or off screen or whether it is not the same
- size as the bitmap. If it is too small, it is read anyway.
- If it is too large, it is clipped at the BitMap boundaries.
- Compressed and masked images are handled correctly.
-
- Returns: TRUE on error, FALSE on success.
-
- Bugs: Doesn't seem to care for Deluxe Paint images with stencils
- attached to them. (I have yet to see anything that handles
- those things right except Deluxe Paint.) All other images
- work correctly, including brushes.
- $end
- */
-
- BOOL ReadPic(bitmap,ifffile,header)
- struct BitMap *bitmap;
- FILE *ifffile;
- BitMapHeader *header;
- {
- BOOL error = FALSE;
- BOOL mask = FALSE;
- BOOL compress = FALSE;
- Chunk bodychunk;
- SHORT scanline,plane,count,needed,read;
- BYTE data,run;
- UBYTE bit_bucket[255];
- UBYTE *dest;
-
- if(header->masking == mskHasMask)
- mask = TRUE; /* got a mask on it ?*/
- if(header->compression == cmpByteRun1)
- compress = TRUE; /* compressed via ByteRun1? */
- needed = header->w/8; /* how many BYTES do we need? */
- if(header->w%8) /* if odd number of pixels, */
- needed++; /* adjust number of bytes needed */
- if(needed%2) /* old word align */
- needed++;
- if(needed<2)
- needed = 2; /* for tiny brushes */
- error = FindChunk(ifffile,MakeID('B','O','D','Y'),&bodychunk);
- if(error)
- return TRUE; /* YIKES! No Body! */
- for(scanline=0;scanline<header->h;scanline++) /* lines first */
- for(plane=0;plane<header->nplanes;plane++) /* then planes */
- {
- if(mask & scanline%2) /* ignore mask */
- dest = bit_bucket; /* toss mask planes */
- else /* figure scanline in bitmap */
- dest = bitmap->Planes[plane]+(scanline*bitmap->BytesPerRow);
- if(!compress) /* not too likely, but easy */
- for(count=0;count<needed;count++)
- *dest++ = fgetc(ifffile);
- else /* image is compressed */
- {
- count=0; /* count is bytes decompressed */
- while(count<needed)
- {
- run = fgetc(ifffile); /* size of run */
- if(run>=0) /* literal run */
- {
- count += run+1;
- for(read=0;read<=run;read++)
- *dest++ = fgetc(ifffile);
- }
- else if (run != 128) /* repeat run */
- {
- run = run*(-1);
- count += run+1;
- data = fgetc(ifffile);
- for(read=0;read<=run;read++)
- *dest++ = data;
- }
- }
- }
- }
- return FALSE;
- }
-
-
- /*
- $doc LoadPicture
- Function: LoadPicture(iff_file,bitmap)
-
- Inputs: FILE *iff_file;
- struct BitMap *bitmap;
-
- Synopsis: Simply loads the requested IFF picture into the bitmap.
- (Note that the caller must do their own colormap setup and
- screen setup. This is about the simplest routine I can
- make for loading pictures and still keep it general enough
- for off-screen loads and such.)
-
- Returns: TRUE on error, FALSE on success.
-
- Bugs: None known.
-
- See Also: ReadPic()
- $end
- */
-
- BOOL LoadPicture(file,bitmap)
- FILE *file;
- struct BitMap *bitmap;
- {
- BOOL error;
- BitMapHeader bmhd;
-
- if(error = GetBMHD(file,&bmhd))
- return TRUE;
- if(error = ReadPic(bitmap,file,&bmhd)) /* decode it */
- return TRUE;
- return FALSE;
- }
-
-
-
- /*
- **********************************************************************
- This part is for sounds. Routines are here for loading, playing,
- and freeing up sounds. This makes adding digitized sounds to a program
- ridiculously easy.
- **********************************************************************
- */
-
-
- /*
- $doc LoadSound
- Function: LoadSound(sound_name)
-
- Inputs: char *sound_name;
-
- Synopsis: LoadSound() takes a pointer to a filename which contains
- an 8SVX sampled sound. It loads this file into memory
- into an ASound structure.
-
- Returns: Pointer to an ASound structure or NULL on failure.
-
- Bugs: None known.
-
- See Also: iff.h (structure definition for ASound).
- $end
- */
-
- struct ASound *LoadSound(name)
- char *name;
- {
- FILE *file;
- Chunk bodychunk;
- BOOL error;
- BYTE *sounddata = NULL;
- ULONG length;
- struct ASound *sound;
-
- if(!(file = fopen(name,"rb")))
- return NULL;
- sound = (struct ASound *)AllocMem(sizeof(struct ASound),MEMF_CLEAR);
- if(!sound)
- {
- fclose(file);
- return NULL;
- }
- GetVoiceHeader(file,&sound->vhead);
- error = FindChunk(file,ID_BODY,&bodychunk);
- if(error)
- {
- FreeMem(sound,sizeof(struct ASound));
- fclose(file);
- return NULL;
- }
- length = sound->vhead.oneShotHiSamples;
- if(!length)
- length = sound->vhead.repeatHiSamples;
- sounddata = (BYTE *)AllocMem(length,MEMF_CLEAR|MEMF_CHIP);
- if(!sounddata)
- {
- FreeMem(sound,sizeof(struct ASound));
- fclose(file);
- return NULL;
- }
- fread(sounddata,bodychunk.cksize,1,file);
- sound->datasize = length;
- sound->data = sounddata;
- return sound;
- }
-
-
- /*
- $doc GetVoiceHeader
- Function: GetVoiceHeader(sound_file,voice_header)
-
- Inputs: FILE *sound_file;
- Voice8Header *voice_header;
-
- Synopsis: Reads an IFF 8SVX file and gets the voice header
- information, storing it into the Voice8Header structure
- passed to it.
-
- Returns: It returns TRUE on success, FALSE on failure.
-
- Bugs: None known.
- $end
- */
-
- BOOL GetVoiceHeader(file,vhead)
- FILE *file;
- Voice8Header *vhead;
- {
- Chunk v8chunk;
- BOOL error;
-
- error = FindChunk(file,ID_VHDR,&v8chunk);
- if(error)
- return FALSE;
- memcpy(vhead,v8chunk.ckdata,v8chunk.cksize);
- FreeMem(v8chunk.ckdata,v8chunk.cksize);
- return TRUE;
- }
-
-
- /*
- $doc OpenAudio
- Function: OpenAudio(void)
-
- Inputs: none
-
- Synopsis: Here's a function that opens the audio device and
- allocates all four channels so that nobody will steal them
- away from you. It also sets up the IOAudio requests for
- all four channels to allow you to play several samples
- simultaneously, if you so desire.
-
- Returns: TRUE on success, FALSE on failure.
-
- Bugs: None known.
- $end
- */
-
- BOOL OpenAudio()
- {
- int count;
- ULONG error = FALSE;
-
- AudioPort = (struct MsgPort *)CreatePort(0,0);
- if(!AudioPort)
- return FALSE;
- for(count=0;count<5;count++)
- {
- if(!(channels[count] = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_CHIP|MEMF_CLEAR)))
- error = TRUE;
- channels[count]->ioa_Request.io_Message.mn_ReplyPort = AudioPort;
-
- }
- if(error)
- {
- for(count=0;count<5;count++)
- {
- if(channels[count])
- FreeMem(channels[count],sizeof(struct IOAudio));
- channels[count] = NULL;
- }
- if(AudioPort)
- DeletePort(AudioPort);
- AudioPort = NULL;
- return FALSE;
- }
- channels[CONTROL]->ioa_Length = 0; /* set to just open device */
- error = OpenDevice("audio.device",0L,(struct IORequest *)channels[CONTROL],0L);
- if(error) /* couldn't get the device! */
- {
- for(count=0;count<5;count++)
- {
- if(channels[count])
- FreeMem(channels[count],sizeof(struct IOAudio));
- channels[count] = NULL;
- }
- if(AudioPort)
- DeletePort(AudioPort);
- AudioPort = NULL;
- return FALSE;
- }
- for(count=0;count<4;count++) /* allocate all four channels */
- {
- channels[count]->ioa_Request.io_Message.mn_Node.ln_Pri = 127; /* No stealing! */
- channels[count]->ioa_Data = &alloc_all_channels[count];
- channels[count]->ioa_Request.io_Device = channels[CONTROL]->ioa_Request.io_Device;
- channels[count]->ioa_Length = 1;
- channels[count]->ioa_Request.io_Command = ADCMD_ALLOCATE;
- channels[count]->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
- BeginIO(channels[count]);
- error = WaitIO(channels[count]);
- if(!(channels[count]->ioa_Request.io_Flags & IOF_QUICK))
- GetMsg(AudioPort);
- if(error)
- break;
- if(channels[count]->ioa_Request.io_Unit != (struct Unit *)alloc_all_channels[count])
- {
- error = TRUE;
- break;
- }
- }
- if(error) /* couldn't get all four channels */
- {
- for(count=0;count<5;count++)
- {
- if(channels[count])
- FreeMem(channels[count],sizeof(struct IOAudio));
- channels[count] = NULL;
- }
- if(AudioPort)
- DeletePort(AudioPort);
- AudioPort = NULL;
- CloseDevice(channels[CONTROL]);
- return FALSE;
- }
- return TRUE;
- }
-
-
-
- /*
- $doc PlaySound
- Function: PlaySound(sound,loops,volume,channel)
-
- Inputs: struct ASound *sound;
- SHORT loops;
- UWORD volume;
- SHORT channel;
-
- Synopsis: PlaySound takes a pointer to an ASound structure (such as
- that returned by LoadSound()), plays it loops number of
- times at the requested volume on the specified channel.
- It does NOT wait for the audio device to return.
-
- Returns: none
-
- Bugs: None known.
- $end
- */
-
- void PlaySound(sound, loops, vol, channel)
- struct ASound *sound;
- SHORT loops;
- UWORD vol;
- SHORT channel;
- {
- ULONG speed;
- ULONG length;
-
- if((channel<0) || (channel>3))
- return;
- length = sound->vhead.oneShotHiSamples;
- if(!length)
- length = sound->vhead.repeatHiSamples;
- speed = NTSC_CLOCK/sound->vhead.samplesPerSec;
- channels[channel]->ioa_Request.io_Command = CMD_WRITE;
- channels[channel]->ioa_Request.io_Flags = ADIOF_PERVOL|ADIOF_NOWAIT|IOF_QUICK;
- channels[channel]->ioa_Volume = vol;
- channels[channel]->ioa_Period = (UWORD)speed;
- channels[channel]->ioa_Cycles = loops;
- channels[channel]->ioa_Data = sound->data;
- channels[channel]->ioa_Length = sound->datasize;
- whichsound[channel] = sound;
- BeginIO((struct IORequest *)channels[channel]);
- return;
- }
-
-
- /*
- $doc FreeSound
- Function: FreeSound(sound)
-
- Inputs: struct ASound *sound;
-
- Synopsis: FreeSound() takes a pointer to an ASound structure and
- frees up all memory associated with it. Before memory is
- freed, the active sounds are checked and if a channel is
- currently playing that sound, a call is made to
- AbortChannel().
-
- Returns: None.
-
- Bugs: None known.
- $end
- */
-
- void FreeSound(sound)
- struct ASound *sound;
- {
- int count;
-
- if(!sound) /* don't hand me no NULLs, dudes... */
- return;
- for(count=0;count<4;count++)
- if(whichsound[count] == sound)
- {
- AbortChannel(count);
- whichsound[count] = NULL;
- }
- if(sound->data)
- FreeMem(sound->data,sound->datasize);
- FreeMem(sound,sizeof (struct ASound));
- return;
- }
-
-
- /*
- $doc CloseAudio
- Function: CloseAudio(void)
-
- Inputs: None.
-
- Synopsis: CloseAudio() just closes down the audio device so other
- programs can have at it. It also frees up all the IOAudio
- requests. It also makes sure the sounds are all aborted
- before closing it all down.
-
- Returns: None.
-
- Bugs: None known.
- $end
- */
-
- void CloseAudio()
- {
- int count;
-
- for(count=0;count<4;count++)
- {
- if(whichsound[count])
- AbortChannel(count);
- CloseDevice(channels[count]);
- if(channels[count])
- FreeMem(channels[count],sizeof(struct IOAudio));
- whichsound[count] = NULL;
- channels[count] = NULL;
- }
- CloseDevice(channels[CONTROL]);
- if(AudioPort)
- DeletePort(AudioPort);
- AudioPort = NULL;
- if(channels[CONTROL])
- FreeMem(channels[count],sizeof(struct IOAudio));
- channels[CONTROL] = NULL;
- return;
- }
-
-
- /*
- $doc WaitSounds
- Function: WaitSounds(sound1,sound2,sound3,sound4)
-
- Inputs: struct ASound *sound1, *sound2, *sound3, *sound4;
-
- Synopsis: WaitSounds() takes pointers to 4 sounds, any or all of
- which can be NULL, and waits on the combination to finish
- playing before returning. Actually it just converts the
- sound pointers to a channel mask and makes a call to
- WaitChannels(), which actually sits there and waits.
-
- Returns: None.
-
- Bugs: None known.
-
- See Also: WaitChannels().
- $end
- */
-
- void WaitSounds(sound1, sound2, sound3, sound4)
- struct ASound *sound1, *sound2, *sound3, *sound4;
- {
- SHORT channelmask = 0;
- int count;
-
- for(count=0;count<4;count++)
- {
- if((whichsound[count] == sound1) && (sound1))
- channelmask |= 1 << count;
- if((whichsound[count] == sound2) && (sound2))
- channelmask |= 1 << count;
- if((whichsound[count] == sound3) && (sound3))
- channelmask |= 1 << count;
- if((whichsound[count] == sound4) && (sound4))
- channelmask |= 1 << count;
- if(channelmask & (1 << count))
- whichsound[count] = NULL;
- }
- if(!channelmask) /* no channels to wait on */
- return;
- WaitChannels(channelmask);
- return;
- }
-
- /*
- $doc
-
- Function: WaitChannels(mask)
-
- Inputs: SHORT mask;
-
- Synopsis: Simply waits for specified sound channels to finish
- playing. Sound channels are specified as a bitmask in
- bits 0-3 where a bit set means to wait on that
- channel. Waits are done in serial fashion. This is
- fine since we want all the channels specified to finish
- before we return. If we wait on one sound and another
- one finishes first, it will be caught on a sebsequent
- pass back through the wait loop.
-
- Returns: None.
-
- Bugs: None known.
- $end
- */
-
- void WaitChannels(mask)
- SHORT mask;
- {
- int count;
-
- for(count=0;count<4;count++)
- if(mask & (1 << count))
- {
- if(CheckIO(channels[count])) /* if sound is done */
- { /* mark it that way */
- while(GetMsg(AudioPort));
- whichsound[count] = NULL;
- }
- else /* if not done, wait */
- { /* for it to finish */
- WaitIO(channels[count]);
- count--; /* and repeat this pass */
- }
- }
- return;
- }
-
-
- /*
- $doc AbortSound
- Function: AbortSound(sound)
-
- Inputs: struct ASound *sound;
-
- Synopsis: AbortSound() aborts playback of a sound, if it is
- currently playing, by figuring out which channel it is
- playing on, then doing a call to AbortChannel for that
- channel.
-
- Returns: None
-
- Bugs: None known.
-
- See Also: iff.h (For whichsound[] array that tracks where sounds are
- currently playing.)
- AbortChannel().
- $end
- */
-
- void AbortSound(sound)
- struct ASound *sound;
- {
- int count;
-
- if(!sound)
- return;
- for(count=0;count<4;count++)
- if(whichsound[count] == sound)
- AbortChannel(count);
- return;
- }
-
- /*
- $doc AbortChannel
- Function: AbortChannel(channel)
-
- Inputs: int channel;
-
- Synopsis: Tells the audio device to finish the sound playing on the
- indicated channel (according to the whichsound[] array).
- Also marks the sound as done in the whichsound[] array.
-
- Returns: None
-
- Bugs: None known.
- $end
- */
-
- void AbortChannel(channel) /* stops a sound and marks it as done */
- int channel;
- {
- channels[CONTROL]->ioa_Request.io_Unit = channels[channel]->ioa_Request.io_Unit;
- channels[CONTROL]->ioa_AllocKey = channels[channel]->ioa_AllocKey;
- channels[CONTROL]->ioa_Request.io_Command = ADCMD_FINISH;
- channels[CONTROL]->ioa_Request.io_Flags = ADIOF_NOWAIT|IOF_QUICK;
- channels[CONTROL]->ioa_Length = 0;
- BeginIO(channels[CONTROL]);
- WaitIO(channels[CONTROL]);
- if(!(channels[CONTROL]->ioa_Request.io_Flags & IOF_QUICK))
- GetMsg(AudioPort);
- whichsound[channel] = NULL;
- return;
- }
-
-
- /*
- $doc StartAudio
- Function: StartAudio(void)
-
- Inputs: None
-
- Synopsis: Sends a command to the audio device to start playing. If
- there are any sounds already queued up (by PlaySound() or
- whatever), they will begin immediately on all channels.
-
- Returns: None
-
- Bugs: None known.
-
- See Also: StopAudio(), LoadSound().
- $end
- */
-
- void StartAudio()
- {
- int count;
-
- for(count=0;count<4;count++)
- {
- channels[4]->ioa_Request.io_Device = channels[count]->ioa_Request.io_Device;
- channels[4]->ioa_AllocKey = channels[count]->ioa_AllocKey;
- channels[4]->ioa_Request.io_Unit = channels[count]->ioa_Request.io_Unit;
- channels[4]->ioa_Length = 0;
- channels[4]->ioa_Request.io_Command = CMD_START;
- BeginIO(channels[4]);
- WaitPort(AudioPort); /* global reply port here */
- GetMsg(AudioPort);
- }
- return;
- }
-
- /*
- $doc StopAudio
- Function: StopAudio(void)
-
- Inputs: None.
-
- Synopsis: Sends a message to the audio device to stop playing. It
- will not clear any sounds that are already queued up, so
- this could be more accurately thought of as a pause in the
- output. Sound will resume when you call StartAudio().
-
- Returns: None.
-
- Bugs: None known.
-
- See Also: StartAudio().
- $end
- */
-
- void StopAudio()
- {
- int count;
-
- for(count=0;count<4;count++)
- {
- channels[4]->ioa_Request.io_Device = channels[count]->ioa_Request.io_Device;
- channels[4]->ioa_AllocKey = channels[count]->ioa_AllocKey;
- channels[4]->ioa_Request.io_Unit = channels[count]->ioa_Request.io_Unit;
- channels[4]->ioa_Length = 0;
- channels[4]->ioa_Request.io_Command = CMD_STOP;
- BeginIO(channels[4]);
- WaitPort(AudioPort);
- GetMsg(AudioPort);
- }
- return;
- }
-
- /*
- $doc AbortAllSounds
- Function: AbortAllSounds(void)
-
- Inputs: None.
-
- Synopsis: Simply aborts all four audio channels and marks them all as
- done.
-
- Returns: None.
-
- Bugs: None known.
-
- See Also: AbortChannel().
- $end
- */
-
- void AbortAllSounds()
- {
- AbortChannel(LEFTA);
- AbortChannel(LEFTB);
- AbortChannel(RIGHTA);
- AbortChannel(RIGHTB);
- return;
- }
-